package com.sky.aspect;

import com.sky.annotation.AutoFill;
import com.sky.constant.AutoFillConstant;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.time.LocalDateTime;

@Component
@Aspect
public class AutoFillAspect {

    /**
     * 对所有打上AutoFill注解的方法做前置增强效果
     * @param joinPoint
     */
    @Before("@annotation(com.sky.annotation.AutoFill)")
    public void autoFill(JoinPoint joinPoint) throws Exception {
        //获取方法参数
        Object args = joinPoint.getArgs()[0];
        //获取参数的class对象
        Class<?> aClass = args.getClass();
        //获取方法签名
        Signature signature = joinPoint.getSignature();
        //强转为 MethodSignature 类型 , 根据方法签名获取方法method对象
        MethodSignature methodSignature =  (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        //根据方法Method对象,获取方法身上的注解@AutoFill
        AutoFill annotation = method.getAnnotation(AutoFill.class);
        //根据注解的对象,获取它里面的Value属性值
        OperationType value = annotation.value();
        //判定是 添加 还是 更新,通过反射来取得对应的4个属性 或者 2个属性 对象
        if (value == OperationType.INSERT){
            //是添加操作,需要设置4个值,通过反射来取得对应的4个属性
            Method setCreateTime = aClass.getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
            Method setUpdateTime = aClass.getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
            Method setCreateUser = aClass.getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
            Method setUpdateUser = aClass.getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER,Long.class);

            //赋值
            setCreateTime.invoke(args, LocalDateTime.now());
            setUpdateTime.invoke(args, LocalDateTime.now());
            setCreateUser.invoke(args, BaseContext.getCurrentId());
            setUpdateUser.invoke(args, BaseContext.getCurrentId());
        }
        if (value == OperationType.UPDATE){
            //是更新操作,需要设置2个值,通过反射来取得对应的2个属性
            Method setUpdateTime = aClass.getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
            Method setUpdateUser = aClass.getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
            //赋值
            setUpdateTime.invoke(args, LocalDateTime.now());
            setUpdateUser.invoke(args, BaseContext.getCurrentId());
        }
    }
}
